home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / os2 / e33el2.zip / emacs / 19.33 / lisp / asm-mode.el < prev    next >
Lisp/Scheme  |  1996-07-02  |  8KB  |  232 lines

  1. ;;; asm-mode.el --- mode for editing assembler code
  2.  
  3. ;; Copyright (C) 1991 Free Software Foundation, Inc.
  4.  
  5. ;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
  6. ;; Maintainer: FSF
  7. ;; Keywords: tools, languages
  8.  
  9. ;; This file is part of GNU Emacs.
  10.  
  11. ;; GNU Emacs is free software; you can redistribute it and/or modify
  12. ;; it under the terms of the GNU General Public License as published by
  13. ;; the Free Software Foundation; either version 2, or (at your option)
  14. ;; any later version.
  15.  
  16. ;; GNU Emacs is distributed in the hope that it will be useful,
  17. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. ;; GNU General Public License for more details.
  20.  
  21. ;; You should have received a copy of the GNU General Public License
  22. ;; along with GNU Emacs; see the file COPYING.  If not, write to the
  23. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  24. ;; Boston, MA 02111-1307, USA.
  25.  
  26. ;;; Commentary:
  27.  
  28. ;; This mode was written by Eric S. Raymond <esr@snark.thyrsus.com>,
  29. ;; inspired by an earlier asm-mode by Martin Neitzel.
  30.  
  31. ;; This minor mode is based on text mode.  It defines a private abbrev table
  32. ;; that can be used to save abbrevs for assembler mnemonics.  It binds just
  33. ;; five keys:
  34. ;;
  35. ;;    TAB        tab to next tab stop
  36. ;;    :        outdent preceding label, tab to tab stop
  37. ;;    comment char    place or move comment
  38. ;;            asm-comment-char specifies which character this is;
  39. ;;            you can use a different character in different
  40. ;;            Asm mode buffers.
  41. ;;    C-j, C-m    newline and tab to tab stop
  42. ;;
  43. ;; Code is indented to the first tab stop level.
  44.  
  45. ;; This mode runs two hooks:
  46. ;;   1) An asm-mode-set-comment-hook before the part of the initialization
  47. ;; depending on asm-comment-char, and
  48. ;;   2) an asm-mode-hook at the end of initialization.
  49.  
  50. ;;; Code:
  51.  
  52. (defvar asm-comment-char ?;
  53.   "*The comment-start character assumed by Asm mode.")
  54.  
  55. (defvar asm-mode-syntax-table nil
  56.   "Syntax table used while in Asm mode.")
  57.  
  58. (defvar asm-mode-abbrev-table nil
  59.   "Abbrev table used while in Asm mode.")
  60. (define-abbrev-table 'asm-mode-abbrev-table ())
  61.  
  62. (defvar asm-mode-map nil
  63.   "Keymap for Asm mode.")
  64.  
  65. (if asm-mode-map
  66.     nil
  67.   (setq asm-mode-map (make-sparse-keymap))
  68.   ;; Note that the comment character isn't set up until asm-mode is called.
  69.   (define-key asm-mode-map ":"        'asm-colon)
  70.   (define-key asm-mode-map "\C-c;"      'comment-region)
  71.   (define-key asm-mode-map "\C-i"    'tab-to-tab-stop)
  72.   (define-key asm-mode-map "\C-j"    'asm-newline)
  73.   (define-key asm-mode-map "\C-m"    'asm-newline)
  74.   )
  75.  
  76. (defconst asm-font-lock-keywords
  77.  '(("^\\(\\(\\sw\\|\\s_\\)+\\)\\>:?[ \t]*\\(\\sw+\\)?"
  78.     (1 font-lock-function-name-face) (3 font-lock-keyword-face nil t))
  79.    ("^\\s +\\(\\(\\sw\\|\\s_\\)+\\)" 1 font-lock-keyword-face))
  80.  "Additional expressions to highlight in Assembler mode.")
  81.  
  82. (defvar asm-code-level-empty-comment-pattern nil)
  83. (defvar asm-flush-left-empty-comment-pattern nil)
  84. (defvar asm-inline-empty-comment-pattern nil)
  85.  
  86. ;;;###autoload
  87. (defun asm-mode ()
  88.   "Major mode for editing typical assembler code.
  89. Features a private abbrev table and the following bindings:
  90.  
  91. \\[asm-colon]\toutdent a preceding label, tab to next tab stop.
  92. \\[tab-to-tab-stop]\ttab to next tab stop.
  93. \\[asm-newline]\tnewline, then tab to next tab stop.
  94. \\[asm-comment]\tsmart placement of assembler comments.
  95.  
  96. The character used for making comments is set by the variable
  97. `asm-comment-char' (which defaults to `?;').
  98.  
  99. Alternatively, you may set this variable in `asm-mode-set-comment-hook',
  100. which is called near the beginning of mode initialization.
  101.  
  102. Turning on Asm mode runs the hook `asm-mode-hook' at the end of initialization.
  103.  
  104. Special commands:
  105. \\{asm-mode-map}
  106. "
  107.   (interactive)
  108.   (kill-all-local-variables)
  109.   (setq mode-name "Assembler")
  110.   (setq major-mode 'asm-mode)
  111.   (setq local-abbrev-table asm-mode-abbrev-table)
  112.   (make-local-variable 'font-lock-defaults)
  113.   (setq font-lock-defaults '(asm-font-lock-keywords))
  114.   (make-local-variable 'asm-mode-syntax-table)
  115.   (setq asm-mode-syntax-table (make-syntax-table))
  116.   (set-syntax-table asm-mode-syntax-table)
  117.  
  118.   (run-hooks 'asm-mode-set-comment-hook)
  119.   ;; Make our own local child of asm-mode-map
  120.   ;; so we can define our own comment character.
  121.   (use-local-map (nconc (make-sparse-keymap) asm-mode-map))
  122.   (local-set-key (vector asm-comment-char) 'asm-comment)
  123.  
  124.   (modify-syntax-entry    asm-comment-char
  125.             "<" asm-mode-syntax-table)
  126.   (modify-syntax-entry    ?\n
  127.              ">" asm-mode-syntax-table)
  128.   (let ((cs (regexp-quote (char-to-string asm-comment-char))))
  129.     (make-local-variable 'comment-start)
  130.     (setq comment-start (concat cs " "))
  131.     (make-local-variable 'comment-start-skip)
  132.     (setq comment-start-skip (concat cs "+[ \t]*"))
  133.     (setq asm-inline-empty-comment-pattern (concat "^.+" cs "+ *$"))
  134.     (setq asm-code-level-empty-comment-pattern (concat "^[\t ]+" cs cs " *$"))
  135.     (setq asm-flush-left-empty-comment-pattern (concat "^" cs cs cs " *$"))
  136.     )
  137.   (make-local-variable 'comment-end)
  138.   (setq comment-end "")
  139.   (make-local-variable 'comment-column)
  140.   (setq comment-column 32)
  141.   (setq fill-prefix "\t")
  142.   (run-hooks 'asm-mode-hook))
  143.  
  144. (defun asm-colon ()
  145.   "Insert a colon; if it follows a label, delete the label's indentation."
  146.   (interactive)
  147.   (save-excursion
  148.     (beginning-of-line)
  149.     (if (looking-at "[ \t]+\\(\\sw\\|\\s_\\)+$")
  150.     (delete-horizontal-space)))
  151.   (insert ":")
  152.   (tab-to-tab-stop)
  153.   )
  154.  
  155. (defun asm-newline ()
  156.   "Insert LFD + fill-prefix, to bring us back to code-indent level."
  157.   (interactive)
  158.   (if (eolp) (delete-horizontal-space))
  159.   (insert "\n")
  160.   (tab-to-tab-stop)
  161.   )
  162.  
  163. (defun asm-line-matches (pattern &optional withcomment)
  164.   (save-excursion
  165.     (beginning-of-line)
  166.     (looking-at pattern)))
  167.  
  168. (defun asm-pop-comment-level ()
  169.   ;; Delete an empty comment ending current line.  Then set up for a new one,
  170.   ;; on the current line if it was all comment, otherwise above it
  171.   (end-of-line)
  172.   (delete-horizontal-space)
  173.   (while (= (preceding-char) asm-comment-char)
  174.     (delete-backward-char 1))
  175.   (delete-horizontal-space)
  176.   (if (bolp)
  177.       nil
  178.     (beginning-of-line)
  179.     (open-line 1))
  180.   )
  181.  
  182.  
  183. (defun asm-comment ()
  184.   "Convert an empty comment to a `larger' kind, or start a new one.
  185. These are the known comment classes:
  186.  
  187.    1 -- comment to the right of the code (at the comment-column)
  188.    2 -- comment on its own line, indented like code
  189.    3 -- comment on its own line, beginning at the left-most column.
  190.  
  191. Suggested usage:  while writing your code, trigger asm-comment
  192. repeatedly until you are satisfied with the kind of comment."
  193.   (interactive)
  194.   (cond
  195.  
  196.    ;; Blank line?  Then start comment at code indent level.
  197.    ((asm-line-matches "^[ \t]*$")
  198.     (delete-horizontal-space)
  199.     (tab-to-tab-stop)
  200.     (insert asm-comment-char comment-start))
  201.  
  202.    ;; Nonblank line with no comment chars in it?
  203.    ;; Then start a comment at the current comment column
  204.    ((asm-line-matches (format "^[^%c\n]+$" asm-comment-char))
  205.     (indent-for-comment))
  206.  
  207.    ;; Flush-left comment present?  Just insert character.
  208.    ((asm-line-matches asm-flush-left-empty-comment-pattern)
  209.     (insert asm-comment-char))
  210.  
  211.    ;; Empty code-level comment already present?
  212.    ;; Then start flush-left comment, on line above if this one is nonempty. 
  213.    ((asm-line-matches asm-code-level-empty-comment-pattern)
  214.     (asm-pop-comment-level)
  215.     (insert asm-comment-char asm-comment-char comment-start))
  216.  
  217.    ;; Empty comment ends line?
  218.    ;; Then make code-level comment, on line above if this one is nonempty. 
  219.    ((asm-line-matches asm-inline-empty-comment-pattern)
  220.     (asm-pop-comment-level)
  221.     (tab-to-tab-stop)
  222.     (insert asm-comment-char comment-start))
  223.  
  224.    ;; If all else fails, insert character
  225.    (t
  226.     (insert asm-comment-char))
  227.  
  228.    )
  229.   (end-of-line))
  230.  
  231. ;;; asm-mode.el ends here
  232.